package com.xbongbong.paas.help;

import com.alibaba.dingtalk.openapi.helper.RestTemplateHelper;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DigestUtil;
import com.xbongbong.paas.toolbox.util.MD5Util;
import com.xbongbong.pro.enums.errorcodes.ProErrorCodeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.TreeSet;

/**
 * @author 吴峰
 * @date 2021/03/17 16:08
 */
@Component
public class HttpHelp {

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpHelp.class);

    @Resource
    private RestTemplateHelper restTemplateHelper;

    /**
     * 发送post/get请求
     * @param header 请求头
     * @param param 请求参数
     * @param url url
     * @see HttpMethod
     * @param httpMethod 请求方法
     * @param httpHeaders 请求头封装类
     * @return
     * @throws XbbException
     */
    public String send(JSONObject header, JSONObject param, String url, HttpMethod httpMethod, HttpHeaders httpHeaders) throws XbbException {
        try {
            switch (httpMethod) {
                case POST:
                    return restTemplateHelper.post(url, param, header, httpHeaders);
                case GET:
                    return restTemplateHelper.get(url, param, header, httpHeaders);
                default:
                    throw new XbbException(ProErrorCodeEnum.API_ERROR_260033);
            }
        } catch (Exception e) {
            LOGGER.error("httpHelp.send出错：", e);
            throw new XbbException(ProErrorCodeEnum.API_ERROR_260034);
        }
    }

    /**
     * 异步请求
     * @param header 请求头
     * @param param 请求参数
     * @param url 请求链接
     * @param httpMethod 请求方法
     * @return void
     * @author 吴峰
     * @date 2021/3/19 17:18
     * @throws XbbException
     */
    public void asyncRequest(JSONObject header, JSONObject param, String url, HttpMethod httpMethod) throws XbbException {
        switch (httpMethod) {
            case POST:
                RestTemplateHelper.asyncPost(url, param, header);
                break;
            case GET:
                RestTemplateHelper.asyncGet(url, param, header);
                break;
            default:
                LOGGER.error("httpHelp.asyncRequest：" + ProErrorCodeEnum.API_ERROR_260033.getMsg()+"："+httpMethod);
                break;
        }
    }

    /**
     * 将密钥放入请求头
     * @param header 请求头
     * @param signature md5密钥
     * @param hmacSecret SHA256密钥
     * @param httpMethod 请求方法
     * @param param 请求参数
     * @param signatureFlag
     * @param hmacSecretFlag
     * @return void
     * @author 吴峰
     * @date 2021/3/18 19:54
     * @throws XbbException
     */
    public static void setHeader(JSONObject header, String signature, String hmacSecret, HttpMethod httpMethod, JSONObject param, Integer signatureFlag, Integer hmacSecretFlag) {
        if (Objects.isNull(header)) {
            header = new JSONObject();
        }
        if (Objects.equals(1, signatureFlag) && Objects.nonNull(param)) {
            signature = getParamString(param, signature);
            signature = MD5Util.EncoderByMd5(signature);
        }
        if (Objects.equals(1, hmacSecretFlag) && Objects.nonNull(param)) {
            hmacSecret = getParamString(param, hmacSecret);
            hmacSecret = DigestUtil.Encrypt(hmacSecret, "SHA-256");
        }
        switch (httpMethod) {
            case POST:
            case GET:
                if (Objects.equals(1, signatureFlag)) {
                    header.put("signature", signature);
                }
                if (Objects.equals(1, hmacSecretFlag)) {
                    header.put("hmacSecret", hmacSecret);
                }
                break;
            default:
                break;
        }
    }

    /**
     * 获取参数的拼装
     * @param param 传参列表 {"value": "传参", "num": 1232}
     * @param signature 秘钥  例如：test
     * @return 传参&1232&test
     * @author 吴峰
     * @date 2021/3/18 9:53
     * @throws XbbException
     */
    private static String getParamString(JSONObject param, String signature) {
        if (Objects.isNull(param)) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        TreeSet<String> treeSet = new TreeSet<>();
        param.forEach((key, v)->{
            treeSet.add(key);
        });
        treeSet.forEach(key->{
            sb.append(param.get(key)).append("&");
        });
        sb.append(signature);
        return sb.toString();
    }
}
